/*******************************************************************************
**
** Photivo
**
** Copyright (C) 2008 Jos De Laender <jos.de_laender@telenet.be>
** Copyright (C) 2010 Michael Munzert <mail@mm-log.com>
**
** This file is part of Photivo.
**
** Photivo is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 3
** as published by the Free Software Foundation.
**
** Photivo is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Photivo.  If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/

#ifndef DLSETTINGS_H
#define DLSETTINGS_H

#include <QtCore>

#include "ptConstants.h"
#include "ptGuiOptions.h"
#include "ptDcRaw.h"
#include "ptInput.h"
#include "ptChoice.h"
#include "ptCheck.h"

////////////////////////////////////////////////////////////////////////////////
//
// ptSettingItem
// Description of any setting.
// Gui elements will be attached and handled via the setting.
// Remark that one never will use this class directly but only
// via its friend class ptSettings. So nothing public.
//
////////////////////////////////////////////////////////////////////////////////

// Some forward declarations.
struct ptGuiInputItem;
struct ptGuiChoiceItem;
struct ptGuiCheckItem;
struct ptItem;

class ptSettingItem {
  // All will be accessed via ptSettings
  friend class ptSettings;

  short    InitLevel;       // the smaller, the longer coming from ini fle
  QVariant DefaultValue;    // Give always one. Maybe nonsensical.
  QVariant Value;
  short    InJobFile;       // Should be in job file ?
  short    GuiType;         // Associated gui type
  short    HasDefaultValue; // For gui : is the default sensical.
  // Remainder is gui related stuff.
  QVariant MinimumValue;
  QVariant MaximumValue;
  QVariant Step;
  short    NrDecimals;
  QString  Label;
  QString  ToolTip;
  const ptGuiOptionsItem * InitialOptions; // For choice (combo) gui elements.

  // Reference to the associated Gui stuff
  ptInput*  GuiInput;
  ptChoice* GuiChoice;
  ptCheck*  GuiCheck;

  // Constructor of an item :
  // Make sure non QVariants all have sensible defaults.
  void ptSettingsItem() {
    InitLevel       = 9; // Never reached.
    InJobFile       = 0;
    GuiType         = ptGT_None;
    HasDefaultValue = 0;
    NrDecimals      = 0;
    InitialOptions  = NULL;
    GuiInput        = NULL;
    GuiCheck        = NULL;
    GuiChoice       = NULL;
  }
}; // End ptSettingItem class.


////////////////////////////////////////////////////////////////////////////////
//
// ptSettings
// This class finally works on underlying ptSettingItem, which
// are shielded. All access and changes via this one.
//
////////////////////////////////////////////////////////////////////////////////

class ptSettings {
Q_DECLARE_TR_FUNCTIONS(ptSettings)

//-------------------------------------

private:
  // We have this private section on top for being able
  // referring to m_Hash already during declaration of class.
  // Hash with the items.
  QHash <QString,ptSettingItem*> m_Hash;

 //-------------------------------------

public:
  // First of all a number of simple accessors to the ptSettingItem
  // characterized by 'Key'
  const QStringList GetKeys()                         { return m_Hash.keys(); }
  short GetGuiType(const QString Key)                 { return m_Hash[Key]->GuiType;}
  short GetHasDefaultValue(const QString Key)         { return m_Hash[Key]->HasDefaultValue;}
  const QVariant GetDefaultValue(const QString Key)   { return m_Hash[Key]->DefaultValue;}
  const QVariant GetMinimumValue(const QString Key)   { return m_Hash[Key]->MinimumValue;}
  const QVariant GetMaximumValue(const QString Key)   { return m_Hash[Key]->MaximumValue;}
  const QVariant GetStep(const QString Key)           { return m_Hash[Key]->Step;}
  short GetNrDecimals(const QString Key)              { return m_Hash[Key]->NrDecimals;}
  const QString GetLabel(const QString Key)           { return m_Hash[Key]->Label;}
  const QString GetToolTip(const QString Key)         { return m_Hash[Key]->ToolTip;}
  const ptGuiOptionsItem* GetInitialOptions(const QString Key)    { return m_Hash[Key]->InitialOptions;}
  short GetInJobFile(const QString Key)               { return m_Hash[Key]->InJobFile;}

  // Low level access to the underlying QWidget
  QWidget* GetGuiWidget(const QString Key);

  // Constructor
  // The InitLevel determines how much of the .ini information is preserved.
  // If InitLevel > InitLevelOfItem the initialization of that Item is
  // preserved from the .ini.
  // So ptSettings(0) would keep no setting at all. As InitLevelOfItem > 0.
  // If InitLevelOfItem = 9 then the item will never be initialized from
  // the .ini as InitLevel<9 (asserted).
  ptSettings(const short InitLevel, const QString Path);

  // Destructor
  ~ptSettings();

  // Accessors to the Value part of a setting.
  // Selfexplaining.
  int    GetInt(const QString Key);
  double GetDouble(const QString Key);
  const QString     GetString(const QString Key);
  const QStringList GetStringList(const QString Key);
  // This should be avoided as much as possible and replaced by above.
  // It is needed though, for instance while writing a job file.
  const QVariant GetValue(const QString Key);

  // Setting of value. Implies update for gui element, if one.
  void  SetValue(const QString Key, const QVariant Value);
  // Other selfexplaining settings. Make only sense for gui elements.
  void  SetEnabled(const QString Key, const short Enabled);
  void  SetMaximum(const QString Key, const QVariant Maximum);
  void  Show(const QString Key, const short Show);

  // Some accessors by GuiName
  QString ToolGetName (const QString GuiName) const;
  int ToolAlwaysVisible(const QString GuiName) const;
  int ToolIsActive (const QString GuiName) const;
  int ToolIsBlocked (const QString GuiName) const;
  int ToolIsHidden (const QString GuiName) const;

  // Methods specific for choice (combo) type of gui elements.

  // Keeps Value unique in the choice.
  void  AddOrReplaceOption(const QString  Key,
                           const QString  Text,
                           const QVariant Value);
  void  ClearOptions(const QString Key, const short WithDefault = 0);
  int   GetNrOptions(const QString Key);
  // Value of the combobox at a certain index position.
  const QVariant    GetOptionsValue(const QString Key, const int Index);
  // Current text of the combobox.
  const QString     GetCurrentText(const QString Key);

  // Following are only used by ptMainWindow when inserting
  // the gui elements in the ptMainWindow. They provide an access
  // to one of the underlying gui elements.
  void SetGuiInput(const QString Key, ptInput* Input);
  void SetGuiChoice(const QString Key, ptChoice* Choice);
  void SetGuiCheck(const QString Key, ptCheck* Check);

  // Interface to update the settings to/from dcraw
  void ToDcRaw(ptDcRaw* TheDcRaw);
  void FromDcRaw(ptDcRaw* TheDcRaw);

  // Persistent Settings. Initialization code in ptMain
  // will access it directly.
  QSettings* m_IniSettings;
}; // end class ptSettings

// And we will instantiate one toplevel.
extern ptSettings* Settings;

////////////////////////////////////////////////////////////////////////////////
//
// ptGui*Item
// Initial description (from .i files) of items.
//
////////////////////////////////////////////////////////////////////////////////

// Initial description of a numerical input gui element.
struct ptGuiInputItem {
  QString  KeyName;
  short    GuiType;
  short    InitLevel;
  short    InJobFile;
  short    HasDefaultValue;
  QVariant DefaultValue;
  QVariant MinimumValue;
  QVariant MaximumValue;
  QVariant Step;
  short    NrDecimals;
  QString  Label;
  QString  ToolTip;
};

// Initial description of a choice (combobox) input gui element.
struct ptGuiChoiceItem {
  QString                 KeyName;
  short                   GuiType;
  short                   InitLevel;
  short                   InJobFile;
  short                   HasDefaultValue;
  QVariant                DefaultValue;
  const ptGuiOptionsItem* InitialOptions;
  QString                 ToolTip;
};

// Initial description of a check input gui element.
struct ptGuiCheckItem {
  QString  KeyName;
  short    GuiType;
  short    InitLevel;
  short    InJobFile;
  QVariant DefaultValue;
  QString  Label;
  QString  ToolTip;
};

// Initial description of a simple setting element.
struct ptItem {
  QString  KeyName;
  short    InitLevel;
  QVariant DefaultValue;
  short    InJobFile;
};

#endif

////////////////////////////////////////////////////////////////////////////////
